﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using PolimericosABM.data;

namespace PolimericosABM.services
{
    public class PolimeroService
    {
        public void TestConection()
        {
            string connectionString = GetConnectionString();
            SqlConnection sqlConnection = new SqlConnection(connectionString);

            try
            {
                sqlConnection.Open();
            }
            finally
            { 
                sqlConnection.Dispose();
            }
        }

        public void AgregarPolimero(Polimero polimero)
        {
            string connectionString = GetConnectionString();
            
            using (SqlConnection sqlConnection = new SqlConnection(connectionString))
            {
                sqlConnection.Open();
                /*
                string sqlQuery = "INSERT INTO [tbl_polime] " +
                                    "([Region], [Linea] ,[Estructura] ,[Fase], [Tipo_cadena] ,[Numero_cadena], " +
                                    "[Marca], [Modelo], [Aro_Frio], [Aro_Caliente], [Aro_Linea_Frio], " +
                                    "[Aro_Linea_Caliente], [Fecha_Instalado] ,[Fecha_Reemplazo] ,[Observaciones]) " +
                                    "VALUES " +
                                    "(@region, @linea, @estructura, @fase, @tipo_cadena, @numero_cadena, " +
                                    "@marca, @modelo, @aro_frio, @aro_caliente, @aro_linea_frio, " +
                                    "@Aro_Linea_Caliente, @fecha_Instalado, @fecha_Reemplazo, @observaciones)";
                */
                string sqlQuery = "INSERT INTO [tbl_polime] ";
                // Campos disponibles para insertar
                string Campos = "([Region], [Linea], [Estructura], [Fase], [Tipo_cadena], [Numero_cadena], " +
                                    "[Marca], [Modelo], [Aro_Frio], [Aro_Caliente], [Aro_Linea_Frio], " +
                                    "[Aro_Linea_Caliente], ";
                // Valores disponibles según los campos a insertar
                // Si se excluyen campos y sus valores estos se guardan como NULL en la base de datos
                string Valores = "VALUES " +
                                    "(@region, @linea, @estructura, @fase, @tipo_cadena, @numero_cadena, " +
                                    "@marca, @modelo, @aro_frio, @aro_caliente, @aro_linea_frio, " +
                                    "@Aro_Linea_Caliente, ";

                if (polimero.Fecha_Instalado.HasValue) 
                { 
                    Campos = Campos + "[Fecha_Instalado], ";
                    Valores = Valores + "@fecha_Instalado, ";
                }

                if (polimero.Fecha_Reemplazo.HasValue) 
                { 
                    Campos = Campos + "[Fecha_Reemplazo], ";
                    Valores = Valores + "@fecha_Reemplazo, ";
                }
                Campos = Campos + "[Observaciones]) ";
                Valores = Valores + "@observaciones)";
                // Concateno el string completo que será la sentencia SQL para aplicar el INSERT
                sqlQuery = sqlQuery + Campos + Valores;

                SqlCommand command = new SqlCommand();
                command.Connection = sqlConnection;
                command.CommandText = sqlQuery;

                SqlParameter pRegion = new SqlParameter("region", polimero.Region);
                SqlParameter pLinea = new SqlParameter("linea", polimero.Linea);
                SqlParameter pEstructura = new SqlParameter("estructura", polimero.Estructura);
                SqlParameter pFase = new SqlParameter("fase", polimero.Fase);
                SqlParameter pTipoCadena = new SqlParameter("tipo_cadena", polimero.TipoCadena);
                SqlParameter pNumeroCadena = new SqlParameter("numero_cadena", polimero.NumeroCadena);
                SqlParameter pMarca = new SqlParameter("marca", polimero.Marca);
                SqlParameter pModelo = new SqlParameter("modelo", polimero.Modelo);
                SqlParameter pAroFrio = new SqlParameter("aro_frio", polimero.Aro_Frio);
                SqlParameter pAroCaliente = new SqlParameter("aro_caliente", polimero.Aro_Caliente);
                SqlParameter pAroLineaFrio = new SqlParameter("aro_linea_frio", polimero.Aro_Linea_Frio);
                SqlParameter pAroLineaCaliente = new SqlParameter("aro_linea_caliente", polimero.Aro_Linea_Caliente);

                if (polimero.Fecha_Instalado.HasValue)
                { 
                    SqlParameter pFechaInstalado = new SqlParameter("fecha_Instalado", polimero.Fecha_Instalado.Value);
                    command.Parameters.Add(pFechaInstalado);
                }
                
                if (polimero.Fecha_Reemplazo.HasValue)
                {
                    SqlParameter pFechaReemplazo = new SqlParameter("fecha_Reemplazo", polimero.Fecha_Reemplazo.Value);
                    command.Parameters.Add(pFechaReemplazo);
                }
                SqlParameter pObservaciones = new SqlParameter("observaciones", polimero.Observaciones);

                command.Parameters.Add(pRegion);
                command.Parameters.Add(pLinea);
                command.Parameters.Add(pEstructura);
                command.Parameters.Add(pFase);
                command.Parameters.Add(pTipoCadena);
                command.Parameters.Add(pNumeroCadena);
                command.Parameters.Add(pMarca);
                command.Parameters.Add(pModelo);
                command.Parameters.Add(pAroFrio);
                command.Parameters.Add(pAroCaliente);
                command.Parameters.Add(pAroLineaFrio);
                command.Parameters.Add(pAroLineaCaliente);
                command.Parameters.Add(pObservaciones);

                command.ExecuteNonQuery();
            }
        }

        public bool ExistePolimero(Polimero polimero)
        {
            bool result = false;
            /*
            Tengo que preguntar si el polimerico existe con SELECT COUNT ()?
            */

            string connectionString = GetConnectionString();

            using (SqlConnection sqlConnection = new SqlConnection(connectionString))
            {
                sqlConnection.Open();

                string sqlQuery = "SELECT * FROM tbl_polime WHERE [Region] = @region and [Linea] = @linea and " +
                                  "[Estructura] = @estructura and [Fase] = @fase and [Tipo_cadena] = @tipo_cadena and " + 
                                  "[Numero_cadena] = @numero_cadena";

                SqlCommand command = new SqlCommand(sqlQuery, sqlConnection);

                SqlParameter pRegion = new SqlParameter("region", polimero.Region);
                SqlParameter pLinea = new SqlParameter("linea", polimero.Linea);
                SqlParameter pEstructura = new SqlParameter("estructura", polimero.Estructura);
                SqlParameter pFase = new SqlParameter("fase", polimero.Fase);
                SqlParameter pTipoCadena = new SqlParameter("tipo_cadena", polimero.TipoCadena);
                SqlParameter pNumeroCadena = new SqlParameter("numero_cadena", polimero.NumeroCadena);

                command.Parameters.Add(pRegion);
                command.Parameters.Add(pLinea);
                command.Parameters.Add(pEstructura);
                command.Parameters.Add(pFase);
                command.Parameters.Add(pTipoCadena);
                command.Parameters.Add(pNumeroCadena);

                SqlDataReader sqlDataReader = command.ExecuteReader();
                while (sqlDataReader.Read())
                {
                    if (polimero.Region == sqlDataReader["Region"].ToString())
                    {
                        if (polimero.Linea == sqlDataReader["Linea"].ToString())
                        {
                            if (polimero.Estructura == (int)sqlDataReader["Estructura"])
                            {
                                if (polimero.Fase == (short)sqlDataReader["Fase"])
                                {
                                    // Hay que chequer si TipoCadena es igual en los dos?
                                    if (polimero.TipoCadena == sqlDataReader["Tipo_Cadena"].ToString())
                                    {
                                        // Hay que chequer si NumeroCadena es igual en los dos?
                                        if (polimero.NumeroCadena == (short)sqlDataReader["Numero_cadena"])
                                        {
                                            // El polimerico a insertar tiene un valor no nulo en Fecha_Instalado?
                                            if (polimero.Fecha_Instalado.HasValue)
                                            {
                                                // Si la Fecha_Reemplazo del que esta en la DB no es nula...
                                                if (!(sqlDataReader["Fecha_Reemplazo"] is DBNull))
                                                {
                                                    // ... pregunto si la Fecha_Reemplazo es menor que la Fecha_Instalado del que quiero insertar
                                                    // Si la Fecha_Reemplazo del que esta en la DB es menor, entonces tendría que ser actualizada,
                                                    // por lo tanto hay polimérico en esa posición
                                                    if (polimero.Fecha_Instalado.Value > (DateTime)sqlDataReader["Fecha_Reemplazo"])
                                                    {
                                                        result = true;
                                                    }
                                                }
                                                else // Si la Fecha_Reemplazo del que esta en la DB es nula
                                                {
                                                    // Si la Fecha_Reemplazo del que esta en la DB es nula...
                                                    // tendría que ser actualizada, por lo tanto hay polimérico en esa posición
                                                    if ((sqlDataReader["Fecha_Reemplazo"] is DBNull))
                                                    {
                                                        result = true;
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                if (!polimero.Fecha_Reemplazo.HasValue)
                                                {
                                                    // Esto es: los dos polimericos, el que quiero insertar y el que esta en la DB
                                                    // tienen Fecha_Instalado y Fecha_Reemplazo con valor nulo
                                                    // por lo tanto hay polimérico en esa posición
                                                    if ((sqlDataReader["Fecha_Instalado"] is DBNull) && (sqlDataReader["Fecha_Reemplazo"] is DBNull))
                                                    {
                                                        result = true;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                return result;
            }
        }

        public List<string> GetLineas(string region)
        {
            List<string> result = new List<string>();
            string connectionString = GetConnectionString();

            using (SqlConnection sqlConnection = new SqlConnection(connectionString))
            {
                sqlConnection.Open();

                string sqlQuery = "select distinct linea from tbl_polime where Region = @region";

                SqlCommand command = new SqlCommand(sqlQuery, sqlConnection);
                SqlParameter pRegion = new SqlParameter("region", region);
                command.Parameters.Add(pRegion);

                SqlDataReader sqlDataReader = command.ExecuteReader();
                while (sqlDataReader.Read())
                {
                    result.Add(sqlDataReader.GetString(0));
                }

                return result;
            }
        }

        public List<string> GetEstructuras(string region, string linea)
        {
            List<string> result = new List<string>();
            string connectionString = GetConnectionString();

            using (SqlConnection sqlConnection = new SqlConnection(connectionString))
            {
                sqlConnection.Open();

                string sqlQuery = "select distinct estructura from tbl_polime where Region = @region and Linea = @linea";

                SqlCommand command = new SqlCommand(sqlQuery, sqlConnection);
                SqlParameter pRegion = new SqlParameter("region", region);
                SqlParameter pLinea = new SqlParameter("linea", linea);
                command.Parameters.Add(pRegion);
                command.Parameters.Add(pLinea);

                SqlDataReader sqlDataReader = command.ExecuteReader();
                while (sqlDataReader.Read())
                {
                    /* Al combobox debo llenarlo con Strings, por eso uso el ToString */
                    result.Add(sqlDataReader.GetInt32(0).ToString());
                }

                return result;
            }
        }

        // Obtener todas las marcas registradas en la base de datos
        public List<string> GetMarcas()
        {
            List<string> result = new List<string>();
            string connectionString = GetConnectionString();

            using (SqlConnection sqlConnection = new SqlConnection(connectionString))
            {
                sqlConnection.Open();

                string sqlQuery = "select distinct marca from tbl_polime";

                SqlCommand command = new SqlCommand(sqlQuery, sqlConnection);

                SqlDataReader sqlDataReader = command.ExecuteReader();
                while (sqlDataReader.Read())
                {
                    result.Add(sqlDataReader.GetString(0));
                }

                return result;
            }
        }

        // Obtener todos los modelos registrados en la base de datos según la marca especificada
        public List<string> GetModelos(string marca)
        {
            List<string> result = new List<string>();
            string connectionString = GetConnectionString();

            using (SqlConnection sqlConnection = new SqlConnection(connectionString))
            {
                sqlConnection.Open();

                string sqlQuery = "select distinct modelo from tbl_polime where Marca = @marca";

                SqlCommand command = new SqlCommand(sqlQuery, sqlConnection);
                SqlParameter pMarca = new SqlParameter("marca", marca);
                command.Parameters.Add(pMarca);
                
                SqlDataReader sqlDataReader = command.ExecuteReader();
                while (sqlDataReader.Read())
                {
                    /* Al combobox debo llenarlo con Strings, por eso uso el ToString */
                    result.Add(sqlDataReader.GetString(0));
                }

                return result;
            }
        }

        public List<Polimero> GetPolimeroByFilter(PolimeroFilter filter)
        {
            List<Polimero> result = new List<Polimero>();
            string connectionString = GetConnectionString();

            using (SqlConnection sqlConnection = new SqlConnection(connectionString))
            {
                sqlConnection.Open();

                string sqlQuery = "SELECT [Region], [Linea], [Estructura] ,[Fase] ,[Tipo_cadena] ,[Numero_cadena], "+
                                  "[polimeID], [Marca], [Modelo], [Aro_Frio], [Aro_Caliente], [Aro_Linea_Frio], "+ 
                                  "[Aro_Linea_Caliente], [Fecha_Instalado], [Fecha_Reemplazo] ,[Observaciones] "+
                                  "FROM [tbl_polime] "+
                                  " WHERE [Marca] LIKE @marca";

                SqlCommand command = new SqlCommand(sqlQuery, sqlConnection);

                SqlParameter pMarca = new SqlParameter("marca", "%" + filter.Marca + "%");
                command.Parameters.Add(pMarca);

                SqlDataReader sqlDataReader = command.ExecuteReader();
                while (sqlDataReader.Read())
                {
                    Polimero polimero = new Polimero();
                    polimero.Region = sqlDataReader["Region"].ToString();
                    polimero.Linea = sqlDataReader["Linea"].ToString();
                    polimero.Estructura = (int) sqlDataReader["Estructura"];
                    polimero.Fase = (short)sqlDataReader["Fase"];
                    polimero.TipoCadena = sqlDataReader["Tipo_cadena"].ToString();
                    polimero.NumeroCadena = (short)sqlDataReader["Numero_cadena"];
                    polimero.PolimeId = (int)sqlDataReader["polimeID"];
                    polimero.Marca = sqlDataReader["Marca"].ToString();
                    polimero.Modelo = sqlDataReader["Modelo"].ToString();
                    polimero.Aro_Frio = (bool)sqlDataReader["Aro_Frio"];
                    polimero.Aro_Caliente = (bool)sqlDataReader["Aro_Caliente"];
                    polimero.Aro_Linea_Frio = (bool)sqlDataReader["Aro_Linea_Frio"];
                    polimero.Aro_Linea_Caliente = (bool)sqlDataReader["Aro_Linea_Caliente"];
                    if (!(sqlDataReader["Fecha_Instalado"] is DBNull))
                    {
                        polimero.Fecha_Instalado = (DateTime)sqlDataReader["Fecha_Instalado"];
                    }

                    if (!(sqlDataReader["Fecha_Reemplazo"] is DBNull))
                    {
                        polimero.Fecha_Reemplazo = (DateTime)sqlDataReader["Fecha_Reemplazo"];
                    }

                    polimero.Observaciones = sqlDataReader["Observaciones"].ToString();

                    result.Add(polimero);
                }

                return result;
            }            
        }

        public List<Polimero> GetPolimeroByLocation(PolimeroFilter filter)
        {
            List<Polimero> result = new List<Polimero>();
            string connectionString = GetConnectionString();

            using (SqlConnection sqlConnection = new SqlConnection(connectionString))
            {
                sqlConnection.Open();

                string sqlQuery = "SELECT * FROM tbl_polime WHERE [Region] = @region and [Linea] = @linea and " +
                                  "[Estructura] = @estructura and [Fase] = @fase";

                SqlCommand command = new SqlCommand(sqlQuery, sqlConnection);

                SqlParameter pRegion = new SqlParameter("region", filter.Region);
                SqlParameter pLinea = new SqlParameter("linea", filter.Linea);
                SqlParameter pEstructura = new SqlParameter("estructura", filter.Estructura);
                SqlParameter pFase = new SqlParameter("fase", filter.Fase);
                
                command.Parameters.Add(pRegion);
                command.Parameters.Add(pLinea);
                command.Parameters.Add(pEstructura);
                command.Parameters.Add(pFase);
                
                SqlDataReader sqlDataReader = command.ExecuteReader();
                while (sqlDataReader.Read())
                {
                    Polimero polimero = new Polimero();
                    polimero.Region = sqlDataReader["Region"].ToString();
                    polimero.Linea = sqlDataReader["Linea"].ToString();
                    polimero.Estructura = (int)sqlDataReader["Estructura"];
                    polimero.Fase = (short)sqlDataReader["Fase"];
                    polimero.TipoCadena = sqlDataReader["Tipo_cadena"].ToString();
                    polimero.NumeroCadena = (short)sqlDataReader["Numero_cadena"];
                    polimero.PolimeId = (int)sqlDataReader["polimeID"];
                    polimero.Marca = sqlDataReader["Marca"].ToString();
                    polimero.Modelo = sqlDataReader["Modelo"].ToString();
                    polimero.Aro_Frio = (bool)sqlDataReader["Aro_Frio"];
                    polimero.Aro_Caliente = (bool)sqlDataReader["Aro_Caliente"];
                    polimero.Aro_Linea_Frio = (bool)sqlDataReader["Aro_Linea_Frio"];
                    polimero.Aro_Linea_Caliente = (bool)sqlDataReader["Aro_Linea_Caliente"];
                    if (!(sqlDataReader["Fecha_Instalado"] is DBNull))
                    {
                        polimero.Fecha_Instalado = (DateTime)sqlDataReader["Fecha_Instalado"];
                    }

                    if (!(sqlDataReader["Fecha_Reemplazo"] is DBNull))
                    {
                        polimero.Fecha_Reemplazo = (DateTime)sqlDataReader["Fecha_Reemplazo"];
                    }

                    polimero.Observaciones = sqlDataReader["Observaciones"].ToString();

                    result.Add(polimero);
                }

                return result;
            }
        }

        private string GetConnectionString()
        {
            return ConfigurationManager.AppSettings["connectionString"];
        }
    }
}
